package org.hfy.collections.helper;

import org.hfy.Constants;

/**
 * @Description: 产生式
 * @Author: Takagi
 * @date: 2023/4/23
 */
public class Production {
    public Symbol left;
    public SymbolString right;

    public Production() {
        this.left = new Symbol();
        this.right = new SymbolString();
    }

    /*
     * @Author Takagi
     * @Description: 获取产生式右侧符号个数
     * @date: 2023/4/25
     * @param
     * @return * @return int
     **/
    public int getRightSize() {
        return this.right.symbolList.size();
    }

    /*
     * @Author Takagi
     * @Description: 获取去除 item 后的产生式右侧
     * @date: 2023/4/25
     * @param
     * @return * @return SymbolString
     **/
    public SymbolString getRightIgnoreItem() {
        SymbolString symbolString = new SymbolString();
        for (Symbol symbol : right.symbolList) {
            if (Constants.isLR0Item(symbol)) continue;
            symbolString.addSymbol(symbol);
        }
        return symbolString;
    }

    /*
     * @Author Takagi
     * @Description: 获取忽略圆点和搜索符的产生式
     * @date: 2023/5/13
     * @param
     * @return * @return Production
     **/
    public Production getProductionIgnoreItem() {
        SymbolString symbolString = new SymbolString();
        SymbolString string = this.getRightIgnoreItem();
        for (Symbol symbol : string.symbolList) {
            if (Constants.isSearchSymbolSeparator(symbol)) break;
            symbolString.addSymbol(symbol);
        }
        return new Production(this.left, symbolString);
    }

    /*
     * @Author Takagi
     * @Description: 获取 item 右移一位后的产生式
     * @date: 2023/4/25
     * @param
     * @return * @return Production
     **/
    public Production getNextItem() {
        Production next = new Production();
        next.left = this.left;
        next.right = this.getRightIgnoreItem();
        int idx = this.right.indexOfItem();
        if (idx == -1 || idx == this.getRightSize() - 1) {
            return null;
        } else {
            next.right.addSymbol(idx + 1, new LR0Item());
            return next;
        }
    }

    /*
     * @Author Takagi
     * @Description: 获取 LR0 项目的下一个符号
     * @date: 2023/4/25
     * @param
     * @return * @return Symbol
     **/
    public Symbol getItemNextSymbol() {
        return right.getItemNextSymbol();
    }

    public Production(Symbol left, SymbolString right) {
        this.left = left;
        this.right = right;
    }

    @Override
    public String toString() {
        return left + Constants.BLANK + Constants.PRODUCT + Constants.BLANK + right;
    }

    @Override
    public boolean equals(Object other) {
        if (other instanceof Production) {
            return ((Production) other).left.equals(this.left) && ((Production) other).right.equals(this.right);
        }
        return false;
    }

    @Override
    public int hashCode() {
        return left.hashCode() + right.hashCode();
    }
}
